﻿#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.IO.Compression;

#endregion
//courtesy of Peter A. Bromberg, Ph.D. http://www.eggheadcafe.com/articles/20041128.asp

namespace Utils
    {

    public class DataSetCodec
        {
        /* remove the comments to test as separate project 
        #region Main Function
        static void Main ( string [ ] args )
            {
            DataSetCodec dsc = new DataSetCodec ( );
            DataSet ds = new DataSet ( );
            ds.Tables.Add ( "Table" );
            ds.Tables [ 0 ].Columns.Add ( "include" );
            ds.Tables [ 0 ].Columns.Add ( "filledValue" );

            DataRow row = ds.Tables [ 0 ].NewRow ( );
            row [ "include" ] = true;
            row [ "filledValue" ] = "some value";
            ds.Tables [ 0 ].Rows.Add ( row );
            Debugger.DebugDataSet ( "ok?", ref ds );


            //now start compression 
            byte [ ] compressedDataSetInBytes = DataSetCodec.CompressDataSet ( ref ds );
            int lengthOfArray = compressedDataSetInBytes.Length;

            //NOW SHOW THE BYTES 
            foreach (byte b in compressedDataSetInBytes)
                {
                Debugger.WriteByte ( b );
                }


            //now decompress
            DataSetCodec.DecompressDataSet ( ref compressedDataSetInBytes, out lengthOfArray );
            Debugger.DebugDataSet ( "ok?", ref ds );


            } //eof main 
        #endregion
        */


        // private ctor; all members are static
        private DataSetCodec ( )
            {
            }

        public static byte [ ] CompressDataSet ( ref DataSet ds )
            {
            ds.RemotingFormat = SerializationFormat.Binary;
            BinaryFormatter bf = new BinaryFormatter ( );
            MemoryStream ms = new MemoryStream ( );
            bf.Serialize ( ms, ds );
            byte [ ] inbyt = ms.ToArray ( );
            System.IO.MemoryStream objStream = new MemoryStream ( );
            System.IO.Compression.DeflateStream objZS =
                  new System.IO.Compression.DeflateStream ( objStream,
                               System.IO.Compression.CompressionMode.Compress );
            objZS.Write ( inbyt, 0, inbyt.Length );
            objZS.Flush ( );
            objZS.Close ( );
            return objStream.ToArray ( );
            }


        public static DataSet DecompressDataSet ( ref byte [ ] bytDs, out int len )
            {
            Utils.Debugger.WriteIf ( bytDs.Length.ToString ( ) );
            DataSet outDs = new DataSet ( );
            MemoryStream inMs = new MemoryStream ( bytDs );
            inMs.Seek ( 0, 0 );
            DeflateStream zipStream = new DeflateStream ( inMs, CompressionMode.Decompress, true );
            byte [ ] outByt = ReadFullStream ( zipStream );
            zipStream.Flush ( );
            zipStream.Close ( );
            MemoryStream outMs = new MemoryStream ( outByt );
            outMs.Seek ( 0, 0 );
            outDs.RemotingFormat = SerializationFormat.Binary;
            BinaryFormatter bf = new BinaryFormatter ( );
            len = (int)outMs.Length;
            outDs = (DataSet)bf.Deserialize ( outMs, null );
            return outDs;
            } //eof public static DataSet DecompressDataSet (ref byte [] bytDs , out int len)


        public static byte [ ] ReadFullStream ( Stream stream )
            {
            byte [ ] buffer = new byte [ 32768 ];
            using (MemoryStream ms = new MemoryStream ( ))
                {
                while (true)
                    {
                    int read = stream.Read ( buffer, 0, buffer.Length );
                    if (read <= 0)
                        return ms.ToArray ( );
                    ms.Write ( buffer, 0, read );
                    }

                } //eof using
            } //eof public static byte [] ReadFullStream
        } //eof class
    } //eof namespace CompressDecompress




